tests: System/compatibility tests for testing shim compatiblity#1218
tests: System/compatibility tests for testing shim compatiblity#1218gkevinzheng merged 14 commits intov3_stagingfrom
Conversation
daniel-sanche
left a comment
There was a problem hiding this comment.
A couple comments for now, but I'll look at the tests in more detail soon
| env_vars: { | ||
| key: "NOX_SESSION" | ||
| value: "system-3.12" | ||
| } No newline at end of file |
There was a problem hiding this comment.
I pulled in main, so this shouldn't be necessary anymore
| self._row_merger = _RowMerger(self._row_merger.last_seen_row_key) | ||
| self.response_iterator = self.read_method(retry_request) | ||
| self.response_iterator = self.read_method(retry_request, retry=self.retry) | ||
|
|
There was a problem hiding this comment.
why was this change needed?
There was a problem hiding this comment.
This change was needed because the read_rows method that gets passed in gets called with the GAPIC default retry instead of the retry that the user passed in or DEFAULT_READ_RETRY for this instance. If there's an error with this specific instance of self.read_method it doesn't get retried and errors out.
For example, if a retriable InternalError occurred mid-stream, then in this on_error handler the same error occurred, the error in the on_error handler would not be retried because the specific retry was not passed in for that RPC call.
There was a problem hiding this comment.
I'm a bit torn, because this does feel like a very real bug. But the code here is also very complex, so I'm hesitant to make changes to the retry policy in case there are side-effects we're not considering
But I guess this is coming in the context of adding more system tests. Do you think the tests we have now are sufficient to catch any errors?
There was a problem hiding this comment.
Actually, on second thought, this is a PR into the v3_staging branch, not main. We will be doing much more extensive changes here as part of the shim, before cutting a release. So I think adding this fix makes sense
| class SelectiveMethodsErrorInjector(UnaryStreamClientInterceptor): | ||
| def __init__(self): | ||
| # As long as there are more items on this list, the items on the list | ||
| # are as follows: |
There was a problem hiding this comment.
I assume after the list is exhausted, it always behaves as normal?
There was a problem hiding this comment.
Yes, it should. I'll put a comment for that.
| data_table, rows_to_delete, row_keys, columns, CELL_VAL_READ_ROWS_RETRY | ||
| ) | ||
|
|
||
| yield data_table |
There was a problem hiding this comment.
Isn't this re-populating the table before each test function? Is that necessary?
There was a problem hiding this comment.
Let me refactor the read_rows system tests to reconfigure the error injector instead of re-populating the table before each test function.
There was a problem hiding this comment.
I'm a bit confused by the organization here. Why are some tests in a class, and others stand-alone? Do we need a separate fixture to populate the table? Do we really want to re-populate the table more than once per run?
There was a problem hiding this comment.
Maybe take a look at the metrics tests, and see if you can structure things that way. Instead of building a new data_table_read_rows_with_error_injector for each function, you can build it once and clear its state between functions
|
|
||
|
|
||
| def _populate_table(data_table, rows_to_delete, row_keys): | ||
| def _add_test_error_handler(retry): |
There was a problem hiding this comment.
a docstring could be helpful here
It looks like it overrides the on_error function to assert that backoff values are within expected bounds?
| self._row_merger = _RowMerger(self._row_merger.last_seen_row_key) | ||
| self.response_iterator = self.read_method(retry_request) | ||
| self.response_iterator = self.read_method(retry_request, retry=self.retry) | ||
|
|
There was a problem hiding this comment.
I'm a bit torn, because this does feel like a very real bug. But the code here is also very complex, so I'm hesitant to make changes to the retry policy in case there are side-effects we're not considering
But I guess this is coming in the context of adding more system tests. Do you think the tests we have now are sufficient to catch any errors?
| self._row_merger = _RowMerger(self._row_merger.last_seen_row_key) | ||
| self.response_iterator = self.read_method(retry_request) | ||
| self.response_iterator = self.read_method(retry_request, retry=self.retry) | ||
|
|
There was a problem hiding this comment.
Actually, on second thought, this is a PR into the v3_staging branch, not main. We will be doing much more extensive changes here as part of the shim, before cutting a release. So I think adding this fix makes sense
| data_table, rows_to_delete, row_keys, columns, CELL_VAL_READ_ROWS_RETRY | ||
| ) | ||
|
|
||
| yield data_table |
There was a problem hiding this comment.
I'm a bit confused by the organization here. Why are some tests in a class, and others stand-alone? Do we need a separate fixture to populate the table? Do we really want to re-populate the table more than once per run?
| for row in rows_to_delete: | ||
| row.clear() | ||
| row.delete() | ||
| row.commit() |
There was a problem hiding this comment.
You should use a try...finally block to make sure resources are fully deleted, anywhere you spin up new resources. (Especially for clusters and tables)
| data_table, rows_to_delete, row_keys, columns, CELL_VAL_READ_ROWS_RETRY | ||
| ) | ||
|
|
||
| yield data_table |
There was a problem hiding this comment.
Maybe take a look at the metrics tests, and see if you can structure things that way. Instead of building a new data_table_read_rows_with_error_injector for each function, you can build it once and clear its state between functions
Additional system tests for testing shim compatibility with the classic client interface.
Also fixes a bug where encountering a retriable error after another retriable error mid-stream raised an exception instead of retrying.
Fixes #1156